#include "GraphView.h"

GraphView::GraphView(QWidget* parent):
    QGraphicsView(parent)
{
    this->setMouseTracking(true);
    this->setBackgroundBrush(Qt::transparent);
    scene=new QGraphicsScene();
    this->setScene(scene);
    this->setRenderHint(QPainter::Antialiasing);
    this->setCursor(Qt::CrossCursor);
    this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    setResizeAnchor(QGraphicsView::AnchorUnderMouse);
    for(int i=0;i<inf;i++)
        for(int j=0;j<inf;j++)
            adj[i][j]=inf;
    state=0;
    start=nullptr;
    end=nullptr;
}

void GraphView::mousePressEvent(QMouseEvent *event)
{
    QPointF TempPos=mapToScene(event->pos());
    int selection=0;
    for(int i=0;i<Vertex::VertexCount;i++)
        if(SameVex(TempPos,vertex[i]->point)){
            if(event->button()==Qt::MouseButton::RightButton){
                qDebug()<<"DelVex";
                DelVex(vertex[i]);
            }
            else{
                if(start==nullptr){
                    start=vertex[i];
                    start->selected=1;
                    start->update();
                    qDebug()<<"SelectedStart";
                }
                else {if(end==nullptr&&vertex[i]!=start){
                    end=vertex[i];
                    end->selected=1;
                    end->update();
                    qDebug()<<"SelectedEnd";
                    //AddArc(start,end);
                }
                else qDebug()<<"ExcessVertex";}
            }
            selection=1;
        }
    if(selection==0){
        QPointF ScePos=mapToScene(event->pos());
        AddVex(ScePos);
    }
};

bool GraphView::SameVex(QPointF a,QPointF b){
    qreal dis=sqrt(pow((a.x()-b.x()),2)+pow(a.y()-b.y(),2));
    if(dis<=20)return true;
    else return false;
}

void GraphView::AddVex(QPointF ScePos){
    Vertex* NewVex=new Vertex(ScePos);
    scene->addItem(NewVex);
    vertex[Vertex::VertexCount-1]=NewVex;
}

void GraphView::DelVex(Vertex *TempVex){
    for(int i=TempVex->id;i<Vertex::VertexCount;i++){
        vertex[i]=vertex[i+1];
        if(i!=Vertex::VertexCount-1){
            vertex[i]->id--;
            vertex[i]->update();
        }
    }
    /*for(int j=TempVex->id;j<Vertex::VertexCount;j++){
        for(int k=0;k<Vertex::VertexCount;k++){
            adj[j][k]=adj[j+1][k];
        }
    }
    for(int j=TempVex->id;j<Vertex::VertexCount;j++){
        for(int k=0;k<Vertex::VertexCount;k++){
            adj[k][j]=adj[k][j+1];
        }
    }*/
    int i=0;
    while(i!=EdgeCount){
        if(edge[i]->start==TempVex||edge[i]->end==TempVex){
            scene->removeItem(edge[i]);
            EdgeCount--;
            for(int j=i;j<EdgeCount;j++)
                edge[j]=edge[j+1];
            i--;
        }
        i++;
    }
    vertex[--Vertex::VertexCount]=nullptr;
    scene->removeItem(TempVex);
}

void GraphView::AddArc(Vertex *TempStart, Vertex *TempEnd){
    Edge* NewArc=new Edge(TempStart,TempEnd);
    scene->addItem(NewArc);
    edge[EdgeCount++]=NewArc;
}

void GraphView::DelArc(Edge *TempEdge){
    int i=0;
    for(i=0;i<EdgeCount;i++)
        if(edge[i]==TempEdge)
            break;
    for(int j=i;j<EdgeCount;j++)
        edge[j]=edge[j+1];
    edge[--EdgeCount]=nullptr;
    scene->removeItem(TempEdge);
}

void GraphView::UpdateA(){
    A.resize(Vertex::VertexCount-1,EdgeCount);
    for(int i=0;i<Vertex::VertexCount-1;i++)
        for(int j=0;j<EdgeCount;j++){
            if(edge[j]->start==vertex[i+1])
                A(i,j)=1;
            if(edge[j]->end==vertex[i+1])
                A(i,j)=-1;
            if(edge[j]->start!=vertex[i+1]&&edge[j]->end!=vertex[i+1]){
                A(i,j)=0;
                //qDebug()<<i<<j;
            }
        }
    qDebug()<<"AUpdated";
}

void GraphView::UpdateG(){
    G.resize(EdgeCount,EdgeCount);
    for(int i=0;i<EdgeCount;i++)
        G(i,i)=1/(edge[i]->Z);
    for(int i=0;i<EdgeCount;i++)
        for(int j=0;j<EdgeCount;j++)
            if(i!=j)
                G(i,j)=0;
    G_n=A*G*A.transpose();
}

void GraphView::solve(){
    UpdateA();
    UpdateG();
    UpdateI_s();
    UpdateU_s();
    qDebug()<<I_s(0,0);
    qDebug()<<U_s(0,0);
    U_n=G_n.inverse()*(A*I_s-A*G*U_s);
}

void GraphView::UpdateI_s(){
    I_s.resize(EdgeCount);
    for(int i=0;i<EdgeCount;i++)
        I_s(i,0)=edge[i]->I;
}

void GraphView::UpdateU_s(){
    U_s.resize(EdgeCount);
    for(int i=0;i<EdgeCount;i++)
        U_s(i,0)=edge[i]->U;
}

void GraphView::init(){
    start->selected=0;
    start->update();
    end->selected=0;
    end->update();
}

Edge* GraphView::HasConnection(Vertex *a, Vertex *b){
    for(int i=0;i<EdgeCount;i++)
        if((edge[i]->start==a&&edge[i]->end==b)||(edge[i]->start==b&&edge[i]->end==a))
            return edge[i];
    return nullptr;
}

void GraphView::ParSim(){
    int i=0;
    while(i!=EdgeCount){
        if(edge[i]->Z==0)
            qDebug()<<1;
            for(int j=0;j<Vertex::VertexCount;j++)
                if(vertex[j]!=edge[i]->start&&vertex[j]!=edge[i]->end){
                    qDebug()<<2;
                    if(HasConnection(vertex[j],edge[i]->end)!=nullptr){
                        qDebug()<<3;
                        if(HasConnection(vertex[j],edge[i]->start)!=nullptr){
                            qDebug()<<4;
                            qreal Z1=HasConnection(vertex[j],edge[i]->start)->Z;
                            qreal Z2=HasConnection(vertex[j],edge[i]->end)->Z;
                            qreal Z=Z1*Z2/(Z1+Z2);
                            HasConnection(vertex[j],edge[i]->start)->Z=Z;
                            HasConnection(vertex[j],edge[i]->start)->update();
                        }
                        else
                        {
                            qDebug()<<edge[i]->start->id<<vertex[j]->id;
                            AddArc(vertex[0],vertex[2]);
                            HasConnection(vertex[j],edge[i]->start)->Z=HasConnection(vertex[j],edge[i]->end)->Z;
                            HasConnection(vertex[j],edge[i]->end)->update();
                            qDebug()<<6;
                        }
                        DelArc(HasConnection(vertex[j],edge[i]->end));
                    }
                    DelVex(edge[i]->end);
                    i=0;
                }
        i++;
    }
}
